package com.ruoyi.admin.service.impl;
import java.util.Collection;
import java.util.Date;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.admin.common.enums.ModuleTypeEnum;
import com.ruoyi.admin.domain.Paper;
import com.ruoyi.admin.domain.PaperTopic;
import com.ruoyi.admin.domain.Question;
import com.ruoyi.admin.domain.UserPaper;
import com.ruoyi.admin.mapper.PaperMapper;
import com.ruoyi.admin.model.request.PaperReq;
import com.ruoyi.admin.model.response.PaperDetailResp;
import com.ruoyi.admin.model.response.QuestionInfoResp;
import com.ruoyi.admin.service.PaperService;
import com.ruoyi.admin.service.PaperTopicService;
import com.ruoyi.admin.service.QuestionService;
import com.ruoyi.admin.service.UserPaperService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * (Paper)表服务实现类
 *
 * @author makejava
 * @since 2023-04-06 16:06:35
 */
@Service("paperService")
public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements PaperService {


    @Autowired
    private PaperTopicService paperTopicService;

    @Autowired
    private QuestionService questionService;

    @Autowired
    private UserPaperService userPaperService;

    @Override
    public List<Paper> paperPage(Page<Paper> page, Paper paper){
        return this.page(page, new LambdaQueryWrapper<Paper>()
                .eq(Paper::getPaperType, paper.getPaperType())
        ).getRecords();
    }


    @Override
    public boolean savePaper(PaperReq paperReq){
        Paper paper = new Paper();
        paper.setPaperName(paperReq.getPaperName());
        paper.setPaperType(paperReq.getPaperType());
        paper.setPaperStatus(paperReq.getPaperStatus());
        paper.setCountdown(paperReq.getCountdown());
        paper.setCreateBy(SecurityUtils.getUsername());
        paper.setCreateTime(new Date());
        paper.setDelFlag(0);
        this.save(paper);

        List<PaperTopic> topics = paperReq.getModuleList().stream().map(moduleDTO -> {
            List<PaperReq.TopicDTO> topicList = moduleDTO.getTopicList();
            List<PaperTopic> paperTopics = topicList.stream().map(topicDTO -> {
                PaperTopic paperTopic = new PaperTopic();
                paperTopic.setPaperId(paper.getId());
                paperTopic.setModuleType(moduleDTO.getModuleType());
                paperTopic.setModuleName(moduleDTO.getModuleName());
                paperTopic.setTopic(topicDTO.getTopic());
                paperTopic.setContent(topicDTO.getContent());
                paperTopic.setCreateBy(SecurityUtils.getUsername());
                paperTopic.setCreateTime(new Date());
                paperTopic.setDelFlag(0);
                paperTopicService.save(paperTopic);
                topicDTO.getQuestionList().forEach(questionReq -> {
                    questionReq.setTopicId(paperTopic.getId());
                    questionReq.setModuleType(moduleDTO.getModuleType());
                    questionReq.setPaperId(paper.getId());
                    questionService.saveQuestion(questionReq);
                });
                return paperTopic;
            }).collect(Collectors.toList());
            return paperTopics;
        }).flatMap(Collection::stream).collect(Collectors.toList());
        return true;
    }


    @Override
    public PaperDetailResp paperDetail(Long paperId){
        Paper paper = Optional.ofNullable(this.getById(paperId)).orElseThrow(() ->
                new ServiceException(StringUtils.format("未找到该paperId数据 = {}", paperId))
        );
        PaperDetailResp paperDetailResp = new PaperDetailResp();
        paperDetailResp.setPaperId(paper.getId());
        paperDetailResp.setPaperName(paper.getPaperName());
        paperDetailResp.setPaperType(paper.getPaperType());
        paperDetailResp.setPaperStatus(paper.getPaperStatus());
        paperDetailResp.setCountdown(paper.getCountdown());

        List<PaperTopic> topicList = paperTopicService.list(new LambdaQueryWrapper<PaperTopic>()
                .eq(PaperTopic::getPaperId, paperId)
                .orderByAsc(PaperTopic::getId, PaperTopic::getModuleType)
        );
        Question question = new Question();
        question.setPaperId(paperId);
        List<QuestionInfoResp> questionList = questionService.questionList(question);
        List<PaperDetailResp.ModuleDTO> moduleDTOList = Stream.of(ModuleTypeEnum.values()).map(moduleTypeEnum -> {
            PaperDetailResp.ModuleDTO moduleDTO = new PaperDetailResp.ModuleDTO();
            moduleDTO.setPaperId(paper.getId());
            moduleDTO.setModuleType(moduleTypeEnum.getTypeCode());
            moduleDTO.setModuleName(moduleTypeEnum.getTypeName());

            List<PaperDetailResp.TopicDTO> topicDTOList = topicList.stream()
                    .filter(f -> f.getModuleType().equals(moduleTypeEnum.getTypeCode()))
                    .map(m -> {
                        PaperDetailResp.TopicDTO topicDTO = new PaperDetailResp.TopicDTO();
                        topicDTO.setTopicId(m.getId());
                        topicDTO.setPaperId(m.getPaperId());
                        topicDTO.setModuleType(m.getModuleType());
                        topicDTO.setModuleName(m.getModuleName());
                        topicDTO.setTopic(m.getTopic());
                        topicDTO.setContent(m.getContent());
                        List<QuestionInfoResp> questionInfoResps = questionList.stream()
                                .filter(questionF -> questionF.getTopicId().equals(m.getId()))
                                .collect(Collectors.toList());
                        topicDTO.setQuestionList(questionInfoResps);
                        return topicDTO;
                    }).collect(Collectors.toList());
            moduleDTO.setTopicList(topicDTOList);
            return moduleDTO;
        }).collect(Collectors.toList());
        paperDetailResp.setModuleList(moduleDTOList);
        UserPaper userPaper = new UserPaper();
        userPaper.setPaperId(paper.getId());
        userPaper.setStudentId(SecurityUtils.getUserId());
        userPaper.setPaperScore(0);
        userPaper.setCreateBy(SecurityUtils.getUsername());
        userPaper.setCreateTime(new Date());
        userPaper.setDelFlag(0);
        userPaper.setStatus(0);
        userPaper.setPaperStartTime(new Date());
        userPaperService.save(userPaper);
        paperDetailResp.setUserPaperId(userPaper.getId());
        return paperDetailResp;
    }

}

